In order to protect a host computing system against malicious software—often called “malware”—that can steal or destroy system resources, data, and private information, security software configured to guard against such threats is often implemented in both a kernel mode and a user mode of the host computing system. On at least some occasions, a kernel-level security component may need to send data to a user-level security component, or vice versa, such as to communicate events from one component to the other.
However, the code base for such security software—especially with respect to the source code for enabling communication between kernel-level and user-level components—can vary greatly depending on the type of operating system (OS) employed by the host computing system. This is at least partly due to different techniques used by different types of OS's for enabling communication between kernel-level and user-level components. For instance, some types of OS's load kernel-level components before loading user-level components, while other types of OS's load user-level components before loading kernel-level components, and the source code for allowing communication between kernel-level and user-level components typically must account for this loading order. This presents a problem because an OS-specific code base for security software must be implemented for each of the multiple available types of OS's on the market in order to enable communications between kernel-level and user-level security components.
Even for a given type of OS, the manner of communicating data from user mode to kernel mode may differ from the manner of communicating data in the opposite direction (i.e., from the kernel mode to the user mode). Thus, current systems, in addition to requiring an OS-specific code base for installed security software, must also implement a code base that is asymmetric, meaning different source code is used to enable communication of data from the kernel mode to the user mode, as compared to the source code that enables communication of data in the opposite direction (i.e., from the user mode to the kernel mode).